/**
 * The class ExpTokenizer extends the class StringTokenizer and breaks up a string into tokens in order to identify the type of the tokens
 * @author Michael Fildstein, ID: 309161594     
 * @author Tomer Ben Rachel ID: 021982475     
 */



public class ExpTokenizer extends java.util.StringTokenizer{

/**
 * Copy Constructor that creates a new String expression
 * @param exp A string data type representing the expression
 */


	public ExpTokenizer(String exp) { 
		  super(exp); 
		}
	
/**
 * The method nextElement identifies the type of the token
 * It does this by seeing if the token is any type of arethmetic operation, number or brackets
 * If not, it identifies it as an Errortoken
 * @return An object data type representing the type of the token
 */  
   
	public Object nextElement(){ 
		  CalcToken resultToken = null; 
		  String token =  super.nextToken(); 
		  
		  if (token.equals("+")) 
		      resultToken =  new AddOp(); 
		  else if (token.equals("*")) 
		      resultToken =  new MultiplyOp(); 
		  else if (token.equals("-")) 
		      resultToken =  new SubtractOp();
		  else if (token.equals("/")) 
		      resultToken =  new DivideOp();
		  else if (token.equals("^")) 
		      resultToken =  new PowOp(); 
		  else if (token.equals("("))
			  resultToken =  new OpenBracket();
		  else if (token.equals(")"))
			  resultToken =  new CloseBracket();
		  else if (this.isNumber(token))
			  resultToken = new ValueToken(Double.parseDouble(token));
		  else
			  resultToken = new ErrorToken(token);
		   
		   return resultToken;  
		}
  
/**
 * The function isNumber checks to see if the token we got is a valid number
 * It does this by going over the token (string) and checks if there are only numbers and not letters, out of place decimal points
 * or other characters
 * @param token A string data type representing the number we need to check
 * @return True if the token we have received is a valid number, false otherwise
 */ 
 
	private boolean isNumber (String token){
		boolean ans = true;
		boolean isInMiddle = false;
		 boolean pointexist = false;

				  for (int i = 0 ; i < token.length() && ans ; i ++){
                if ((int)token.charAt(i) < 48 || (int)token.charAt(i) > 57){    //If the character's value is below 48 or above 57 it is not a digit
                    ans = false;
                }    
                if(i > 0 && i < token.length() -1 &&  (int)token.charAt(i) == 46 && !pointexist){   //If the index of the string is not at the very
                       pointexist = true;                                                           //beginning or at the very end and we have encountered
                       ans = true;                                                                  //A decimal point, then it is ok.
                     }                                                                              //If we encounter another decimal point, then we know
                                                                                                    //the token is an ErrorToken
          }
		return ans;
	}
	
	
	
}
